package com.greate.community.service;

import com.greate.community.entity.DiscussPost;
import com.greate.community.entity.User;
import com.greate.community.entity.UserBehavior;
import com.greate.community.mapper.UserBehaviorMapper;
import com.greate.community.util.CommunityConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 用户行为服务
 * 负责用户行为数据的记录和分析
 */
@Service
public class UserBehaviorService implements CommunityConstant {

    private static final Logger logger = LoggerFactory.getLogger(UserBehaviorService.class);

    @Autowired
    private UserBehaviorMapper userBehaviorMapper;

    @Autowired
    private DiscussPostService discussPostService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserTagService userTagService;

    /**
     * 记录用户行为
     * @param userId 用户ID
     * @param entityType 实体类型
     * @param entityId 实体ID
     * @param behaviorType 行为类型
     * @param stayTime 停留时间(秒)
     * @return 行为ID
     */
    public int recordBehavior(int userId, int entityType, int entityId, int behaviorType, int stayTime) {
        if (userId <= 0) {
            throw new IllegalArgumentException("用户ID无效");
        }

        UserBehavior behavior = new UserBehavior();
        behavior.setUserId(userId);
        behavior.setEntityType(entityType);
        behavior.setEntityId(entityId);
        behavior.setBehaviorType(behaviorType);
        behavior.setStayTime(stayTime);
        behavior.setCreateTime(new Date());

        // 根据不同行为类型计算分数
        double score = calculateBehaviorScore(behaviorType, stayTime);
        behavior.setScore(score);

        userBehaviorMapper.insertUserBehavior(behavior);
        
        // 根据用户行为更新用户标签
        updateUserTag(userId, entityType, entityId, behaviorType, score);
        
        return behavior.getId();
    }

    /**
     * 计算行为分数
     * @param behaviorType 行为类型
     * @param stayTime 停留时间(秒)
     * @return 行为分数
     */
    private double calculateBehaviorScore(int behaviorType, int stayTime) {
        // 默认基础分
        double baseScore = 1.0;
        
        // 根据行为类型计算权重
        double typeWeight = 1.0;
        switch (behaviorType) {
            case 1: // 浏览
                typeWeight = 1.0;
                break;
            case 2: // 点赞
                typeWeight = 3.0;
                break;
            case 3: // 评论
                typeWeight = 5.0;
                break;
            case 4: // 收藏
                typeWeight = 8.0;
                break;
            case 5: // 关注
                typeWeight = 10.0;
                break;
            default:
                typeWeight = 1.0;
        }
        
        // 停留时间权重（浏览时长对分数的影响）
        double timeWeight = 1.0;
        if (behaviorType == 1 && stayTime > 0) {
            // 浏览类型，根据停留时间计算权重
            // 最大权重为2.0（当停留时间超过5分钟时）
            timeWeight = Math.min(1.0 + stayTime / 300.0, 2.0);
        }
        
        return baseScore * typeWeight * timeWeight;
    }

    /**
     * 更新用户标签
     * @param userId 用户ID
     * @param entityType 实体类型
     * @param entityId 实体ID
     * @param behaviorType 行为类型
     * @param score 行为分数
     */
    private void updateUserTag(int userId, int entityType, int entityId, int behaviorType, double score) {
        try {
            // 只处理帖子类型的实体
            if (entityType == ENTITY_TYPE_POST) {
                DiscussPost post = discussPostService.findDiscussPostById(entityId);
                if (post != null) {
                    // 从帖子标题和内容中提取关键词作为标签
                    Set<String> tags = extractTags(post.getTitle(), post.getContent());
                    for (String tag : tags) {
                        // 根据行为分数更新标签权重
                        userTagService.addOrUpdateTag(userId, tag, score);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("更新用户标签时出错", e);
        }
    }

    /**
     * 从文本中提取标签
     * @param title 标题
     * @param content 内容
     * @return 标签集合
     */
    private Set<String> extractTags(String title, String content) {
        Set<String> tags = new HashSet<>();
        
        // 简单的标签提取策略，实际项目中可以使用NLP技术提取关键词
        // 这里仅做简单处理，提取标题中的关键词
        if (title != null && !title.isEmpty()) {
            String[] words = title.split("\\s+");
            for (String word : words) {
                if (word.length() >= 2) { // 过滤太短的词
                    tags.add(word);
                }
            }
        }
        
        // 限制标签数量，避免标签过多
        if (tags.size() > 5) {
            Iterator<String> iterator = tags.iterator();
            int count = 0;
            while (iterator.hasNext() && count < 5) {
                iterator.next();
                count++;
            }
            while (iterator.hasNext()) {
                iterator.remove();
            }
        }
        
        return tags;
    }

    /**
     * 获取用户的行为列表
     * @param userId 用户ID
     * @param offset 起始位置
     * @param limit 查询条数
     * @return 用户行为列表
     */
    public List<UserBehavior> getUserBehaviors(int userId, int offset, int limit) {
        return userBehaviorMapper.selectUserBehaviors(userId, offset, limit);
    }

    /**
     * 获取用户的热门行为
     * @param userId 用户ID
     * @param limit 查询条数
     * @return 用户热门行为列表
     */
    public List<UserBehavior> getHotUserBehaviors(int userId, int limit) {
        return userBehaviorMapper.selectHotUserBehaviors(userId, limit);
    }

    /**
     * 根据用户ID和实体类型查询用户行为
     * @param userId 用户ID
     * @param entityType 实体类型
     * @param offset 起始位置
     * @param limit 查询条数
     * @return 用户行为列表
     */
    public List<UserBehavior> getUserBehaviorsByEntityType(int userId, int entityType, int offset, int limit) {
        return userBehaviorMapper.selectUserBehaviorsByEntityType(userId, entityType, offset, limit);
    }

    /**
     * 持久化用户行为到MySQL
     */
    public void saveBehavior(UserBehavior behavior) {
        userBehaviorMapper.insertUserBehavior(behavior);
    }
} 